package org.rvk.vms.service.volunteers;

import org.rvk.vms.api.volunteers.IVolunteersService;
import org.rvk.vms.dal.cache.State;
import org.rvk.vms.dal.cache.VolunteersCache;
import org.rvk.vms.dal.dao.GenericDao;
import org.rvk.vms.dal.dao.GenericJdbcDao;
import org.rvk.vms.dal.entities.Volunteer;
import org.rvk.vms.dal.model.search.SearchInput;
import org.rvk.vms.dal.model.search.SearchResult;
import org.rvk.vms.dal.model.VolunteersSummary;
import org.rvk.vms.utils.search.VolunteersSearchFields;
import org.rvk.vms.utils.search.VolunteersSearchUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Ashish Kumar Sinha <aksinha.mail@gmail.com>
 */
@Service("volunteersService")
@Scope((BeanDefinition.SCOPE_SINGLETON))
public class VolunteersServiceImpl implements IVolunteersService {

    @Autowired
    private VolunteersCache volunteersCache;

    @Autowired
    private GenericJdbcDao genericJdbcDao;

    @Autowired
    private GenericDao genericDao;

    @Autowired
    private VolunteersSearchUtils volunteersSearchUtils;


    /**
     * To get the volunteers summary. Volunteers summary is kind of a report displayed on Voluteers dashboard.
     * Prepare this report and cache is for future use.
     *
     * @return - the volunteers summary
     */
    @Override
    public VolunteersSummary getVolunteersSummary() {
        if(volunteersCache.isVolunteerSummaryValid() == false) {
            cacheVolunteersSummary();
        }
        return volunteersCache.getVolunteersSummary();
    }

    /**
     * search for volunteers.
     *
     * @param searchInput
     * @return the pageable search result
     */
    @Override
    public SearchResult<Volunteer> search(final SearchInput searchInput) {
        List<Volunteer> result = new ArrayList<>();
        Map<VolunteersSearchFields, String> mappedSearchKey = volunteersSearchUtils.interpretWisely(searchInput.getKey());
        SearchResult searchResult = new SearchResult(searchInput, result, 100);

        // call generic search method.
        search(mappedSearchKey, searchResult);
        return searchResult;
    }

    protected void search(final Map<VolunteersSearchFields, String> mapSearchKey, final SearchResult<Volunteer> searchResult){
        if(mapSearchKey == null || mapSearchKey.isEmpty()){ return; }
        String [] jpaQueries = volunteersSearchUtils.buildJpaSearchQuery(mapSearchKey, searchResult.getPageSize(), searchResult.getPage());

        List<Volunteer> result = genericDao.findAllByQuery(Volunteer.class, jpaQueries[0], null);
        searchResult.getResult().clear();
        searchResult.getResult().addAll(result);

        // TODO - Implementation for Count query

    }

    protected void cacheVolunteersSummary(){
       //TODO - take care of multi-threading
        System.out.println("VolunteersServiceImpl.cacheVolunteersSummary ");
        Map<State, Integer> stateWiseVolunteersCount = genericJdbcDao.volunteersCountPerState();
        System.out.println("stateWiseVolunteersCount = " + stateWiseVolunteersCount);
        VolunteersSummary theSummary = volunteersCache.getVolunteersSummary();
        if(theSummary == null){
            theSummary = new VolunteersSummary();
        }
        theSummary.setMapAllStatesVolunteersCount(stateWiseVolunteersCount);
        volunteersCache.setVolunteersSummary(theSummary);
    }

    public VolunteersCache getVolunteersCache() {
        return volunteersCache;
    }

    public GenericJdbcDao getGenericJdbcDao() {
        return genericJdbcDao;
    }

    public VolunteersSearchUtils getVolunteersSearchUtils() {
        return volunteersSearchUtils;
    }
}
